package ddz;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;

import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * 
 * @author 不正
 * 
 */
public class MyServer {
	public static ArrayList<Socket> list = new ArrayList<>();
	public static ArrayList<String> userName = new ArrayList<>();
	public final static int CAN_PLAY_NUM = 3;
	public static boolean isPlay = false;

	public static void main(String[] args) throws IOException, InterruptedException {
		System.out.println("服务器启动");
		new ServerListen().start();
		// 连接人数
		while (true) {
			System.out.println("当前socket数量" + MyServer.list.size());
			System.out.println("当前userName数量" + MyServer.userName.size());
			Thread.sleep(3000);
		}

	}

}

/**
 * 服务器监听线程
 * 
 * @author 不正
 *
 */
class ServerListen extends Thread {

	@Override
	public void run() {
		// TODO 自动生成的方法存根
		// 创建一个ServerSocket，用于监测客户端的socket连接
		ServerSocket serverSocket;
		try {
			serverSocket = new ServerSocket(30000);
			// 采用循环不断接受客户端的请求
			while (true) {
				//如果连接数为三人初始化信息且游戏未开始
				if(!MyServer.isPlay && MyServer.list.size() == MyServer.CAN_PLAY_NUM) {
					new InitThread().start();
				}
				// 每有一个客户端连接服务器，服务器端产生一个Socket
				Socket socket = serverSocket.accept();
				new Thread(new ClientThread(socket)).start();
				synchronized (MyServer.list) {
					MyServer.list.add(socket);
				}

			}

		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}

	}

}
/**
 * 初始化游戏信息
 * @author 不正
 *
 */
class InitThread extends Thread {
	@Override
	public void run() {
		while(true) {
			synchronized (MyServer.list) {
				synchronized (MyServer.userName) {
					// 判断是否符合游戏开始要求 连接数和玩家名称数
					if (MyServer.list.size() == MyServer.CAN_PLAY_NUM
							&& MyServer.userName.size() == MyServer.CAN_PLAY_NUM) {
						initGameData();
						startGame();
						MyServer.isPlay = true;
						break;
					}
				}
			}
		}
	}

	/**
	 * 向客户端发送消息可以开始游戏
	 */
	public void startGame() {
		try {
			for (Iterator<Socket> it = MyServer.list.iterator(); it.hasNext();) {
				Socket socket = it.next();
				try {
					OutputStream os = socket.getOutputStream();
					os.write(("YES" + "\n").getBytes("utf-8"));
				} catch (SocketException e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	/**
	 * 初始化游戏数据
	 */
	public void initGameData() {
		// 所有玩家名称
		String allUserName = "";
		for (String userName : MyServer.userName) {
			allUserName += (userName + "--");
		}
		System.out.println("所有玩家名称:" + allUserName);
		String[] strings = Utils.getPukes();
		int count = 0;
		// 向客户端发送自身手牌
		for (Iterator<Socket> it = MyServer.list.iterator(); it.hasNext();) {
			Socket socket = it.next();
			try {
				OutputStream os = socket.getOutputStream();
				os.write(("s" + strings[count] + "\n").getBytes("utf-8"));
				// 向客户端发送所有玩家名称
				os.write(("u" + allUserName + "\n").getBytes("utf-8"));
				System.out.println("向客户端发送:" + strings[count]);
			} catch (IOException e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			count++;
		}
		// 向客户端发送地主牌
		for (Iterator<Socket> it = MyServer.list.iterator(); it.hasNext();) {
			Socket socket = it.next();
			try {
				OutputStream os = socket.getOutputStream();
				os.write(("t" + strings[3] + "\n").getBytes("utf-8"));
				System.out.println("向客户端发送:" + strings[3]);
			} catch (IOException e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}
}

/**
 * 服务器单独连接客户端线程
 * 
 * @author 不正
 *
 */
class ClientThread implements Runnable {
	// 定义当前处理的socket
	private Socket socket = null;
	// 该线程处理的socket对应输入流
	private BufferedReader br = null;
	// 当前用户名
	private String userName = null;

	public ClientThread(Socket socket) throws UnsupportedEncodingException, IOException {
		// TODO 自动生成的构造函数存根
		this.socket = socket;
		br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
	}

	@Override
	public void run() {
		try {
			String content = null;
			while (true) {
				if ((content = readFromClient()) != null) {
					// 同步锁 防止多客户端同时发送消息冲突
					synchronized (MyServer.list) {
						System.out.println("服务器收到消息:" + content);
						switch (content) {
						// 某客户端发来询问
						case "可以游戏":
							try {
								OutputStream os = socket.getOutputStream();
								// 保证第三台连接后得到是NO
								String canPlay = MyServer.list.size() == MyServer.CAN_PLAY_NUM
										&& MyServer.userName.size() == MyServer.CAN_PLAY_NUM ? "YES" : "NO";
								// 不向第三台连接成功的客户端发送
								if (canPlay.equals("NO")) {
									os.write((canPlay + "\n").getBytes("utf-8"));
									System.out.println("服务器发送消息:" + canPlay);
								}
							} catch (SocketException e) {
								// TODO: handle exception
								e.printStackTrace();
							}
							break;
						case "游戏正常结束":
							for (Iterator<Socket> it = MyServer.list.iterator(); it.hasNext();) {
								Socket socket = it.next();
								if (socket.hashCode() == this.socket.hashCode()) {
									continue;
								}
								try {
									OutputStream os = socket.getOutputStream();
									os.write(("游戏正常结束" + "\n").getBytes("utf-8"));
									System.out.println("服务器发送消息:游戏正常结束");
								} catch (SocketException e) {
									// TODO: handle exception
									e.printStackTrace();
								}
							}
							
							break;
						// 遍历list 向每个客户端发送消息 或者 获取用户名
						default:
							// 客户端发送用户名
							if (content.startsWith("userName:")) {
								synchronized (MyServer.userName) {
									userName = content.split(":")[1].trim();
									System.out.println("用户:" + content.split(":")[1] + "连接");
									MyServer.userName.add(userName);
								}
							} else {
								// 遍历list 向每个客户端发送消息
								for (Iterator<Socket> it = MyServer.list.iterator(); it.hasNext();) {
									Socket socket = it.next();
									if (socket.hashCode() == this.socket.hashCode()) {
										continue;
									}
									try {
										OutputStream os = socket.getOutputStream();
										os.write((content + "\n").getBytes("utf-8"));
									} catch (SocketException e) {
										// TODO: handle exception
										e.printStackTrace();
									}
								}
							}

							break;
						}

					}
				} else {
					// 刪除该socket和该用户名
					synchronized (MyServer.list) {
						MyServer.list.remove(socket);
						System.out.println("list移除一个socket:" + socket.hashCode());
						synchronized (MyServer.userName) {
							MyServer.userName.remove(userName);
							System.out.println("user_list移除一个userName:" + userName);
							//如果玩家全部退出，游戏结束
							if(MyServer.list.size() == 0 && MyServer.userName.size() == 0) {
								MyServer.isPlay = false;
							}
						}
					}

					break;
				}

			}
		} catch (

		IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}

	}

	/**
	 * 读取客户端消息
	 * 
	 * @return
	 */
	private String readFromClient() {
		try {
			return br.readLine();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();

		}
		return null;
	}

}
